home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / comms / internet / html-related / hsc / source / hsclib / linit.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  17KB  |  632 lines

  1. /*
  2.  * hsclib/linit.c
  3.  *
  4.  * functions to init & read preferences for a hsc-process
  5.  *
  6.  * Copyright (C) 1996  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated: 11-Sep-1996
  23.  * created: 19-Feb-1996
  24.  */
  25.  
  26. #include "hsclib/inc_base.h"
  27.  
  28. #include "hsclib/deftag.h"
  29. #include "hsclib/include.h"
  30. #include "hsclib/parse.h"
  31.  
  32. #include "hsclib/tag_a.h"
  33. #include "hsclib/tag_hsc.h"
  34. #include "hsclib/tag_if.h"
  35. #include "hsclib/tag_macr.h"
  36. #include "hsclib/tag_misc.h"
  37.  
  38. #if DEBUG
  39. /*
  40.  * debugging print functions
  41.  */
  42. static VOID prt_ent(FILE * stream, APTR data)
  43. {
  44.     HSCENT *ent = (HSCENT *) data;
  45.  
  46.     if (ent)
  47.     {
  48.         fprintf(stream, " %s", ent->name);
  49.         if (ent->replace)
  50.             fprintf(stream, "=%s", ent->replace);
  51.         if (ent->numeric)
  52.             fprintf(stream, "=%ld", ent->numeric);
  53.     }
  54.     else
  55.         fprintf(stream, " <NULL>");
  56. }
  57.  
  58. static VOID prt_tag(FILE * stream, APTR data)
  59. {
  60.     if (data)
  61.     {
  62.         HSCTAG *tag = (HSCTAG *) data;
  63.         fprintf(stream, " <");
  64.         if (tag->option & HT_CLOSE)
  65.             fprintf(stream, "/");
  66.         if (tag->o_handle)
  67.             fprintf(stderr, "*");
  68.         fprintf(stream, "%s", tag->name);
  69.         if (tag->c_handle)
  70.             fprintf(stderr, "*");
  71.         if (tag->option & HT_REQUIRED)
  72.             fprintf(stream, "/r");
  73.         if (tag->option & HT_ONLYONCE)
  74.             fprintf(stream, "/1");
  75.         if (tag->option & HT_AUTOCLOSE)
  76.             fprintf(stream, "/sc");
  77.         if (tag->option & HT_SPECIAL)
  78.             fprintf(stream, "/a");
  79.         fprintf(stream, ">");
  80.     }
  81.     else
  82.         fprintf(stream, " <NULL>");
  83. }
  84. #endif
  85.  
  86. /* function to temporarily disable debuggin output */
  87. #if 1
  88. static BOOL dbg_old = FALSE;
  89.  
  90. #define dbg_disable(hp) {dbg_old = hp->debug; hp->debug=FALSE;}
  91. #define dbg_restore(hp) {hp->debug=dbg_old;}
  92.  
  93. #else
  94. #define dbg_disable(hp)
  95. #define dbg_restore(hp)
  96. #endif
  97.  
  98. /*
  99.  * find_prefs_fname
  100.  *
  101.  * find preferences file: first check, if it is located
  102.  * somewhere in the paths given via CONFIG_PATH (which
  103.  * is a system depandent symbol); if not, check if it
  104.  * is in the path described in the envvar HSCPREFS
  105.  *
  106.  * result: full path & filename of prefs or NULL if not found
  107.  */
  108. static STRPTR find_prefs_fname(HSCPRC * hp)
  109. {
  110.     STRPTR prefs_fname = NULL;
  111.     STRPTR paths[] =            /* paths to search for config file */
  112.     {"", "", CONFIG_PATH,
  113.      NULL, NULL};
  114.     STRPTR path = NULL;
  115.     UBYTE path_ctr = 0;
  116.     FILE *cfgf = NULL;          /* prefs file */
  117.     STRPTR hscenv = NULL;
  118.     static STRARR cfgfn[300];   /* TODO: expstr; buffer to create
  119.                                  *   filename of config file */
  120.     /* setup path from envvar */
  121.     hscenv = getenv(HSCPREFS_ENVVAR);
  122.     if (hscenv)
  123.     {
  124.         /* copy envvar to own memory area */
  125.         hscenv = strclone(hscenv);
  126.  
  127.         /* strip linefeeds from hscenv */
  128.         while (strlen(hscenv) && (hscenv[strlen(hscenv)] == '\n'))
  129.             hscenv[strlen(hscenv)] = '\0';
  130.  
  131.         /* add hscenv to paths */
  132.         paths[1] = hscenv;
  133.     }
  134.  
  135.     /* try to open any prefs-file */
  136.     do
  137.     {                           /* loop: */
  138.         path = paths[path_ctr]; /*   get next path */
  139.         if (path)
  140.         {                       /*   is it the last one? */
  141.             strcpy(cfgfn, path);        /*   N->generate filename */
  142.             strcat(cfgfn, CONFIG_FILE);
  143.  
  144.             DC(fprintf(stderr, DHL "try \"%s\"\n", cfgfn));
  145.  
  146.             cfgf = fopen(cfgfn, "r");   /*      try to open file */
  147.         }
  148.         path_ctr++;             /*   process next path */
  149.     }
  150.     while (path && (!cfgf));    /* until no path left or file opened */
  151.  
  152.     if (cfgf)
  153.     {
  154.         prefs_fname = cfgfn;
  155.         fclose(cfgf);
  156.     }
  157.  
  158.     ufreestr(hscenv);
  159.  
  160.     return (prefs_fname);
  161. }
  162.  
  163. /*
  164.  * hsc_read_base_info
  165.  *
  166.  * try to open base-file and read where in memory
  167.  * information about defined tags/attributes/entities
  168.  * is located.
  169.  *
  170.  * result: dummy-hsc-process that only contains
  171.  *   the information read from base-file
  172.  *
  173.  * see "LoadHscPrefs/LoadHscPrefs.c"
  174.  */
  175. HSCPRC *hsc_read_base_info(VOID)
  176. {
  177.     HSCPRC *dummy_hp = NULL;
  178.  
  179. #ifdef HSCBASE_FILE
  180.  
  181.     FILE *inpf = fopen(HSCBASE_FILE, "r");
  182.     DLLIST *hp_deftag = NULL;
  183.     DLLIST *hp_defattr = NULL;
  184.     DLLIST *hp_defent = NULL;
  185.  
  186.     if (inpf)
  187.     {
  188.         STRARR s[32];
  189.         APTR p = NULL;
  190.  
  191.         while (fscanf(inpf, "%s %p\n", &(s[0]), &p) != EOF)
  192.         {
  193.             if (!strcmp("DEFTAG", s))
  194.             {
  195.                 hp_deftag = (DLLIST *) p;
  196.                 printf(DHL "deftag  %p\n", hp_deftag);
  197.             }
  198.             else if (!strcmp("DEFATTR", s))
  199.             {
  200.                 hp_defattr = (DLLIST *) p;
  201.                 printf(DHL "defattr %p\n", hp_defattr);
  202.             }
  203.             else if (!strcmp("DEFENT", s))
  204.             {
  205.                 hp_defent = (DLLIST *) p;
  206.                 printf(DHL "defent  %p\n", hp_defent);
  207.             }
  208.             else
  209.             {
  210.                 printf(DHL "%s %p (unknown)\n", s, p);
  211.             }
  212.         }
  213.     }
  214.  
  215.     fclose(inpf);
  216.  
  217.     if (hp_deftag && hp_defattr && hp_defent)
  218.     {
  219.         /* assign information to dummy-process */
  220.         dummy_hp = new_hscprc();
  221.  
  222.         del_dllist(dummy_hp->defattr);
  223.         del_dllist(dummy_hp->defent);
  224.         del_dllist(dummy_hp->deftag);
  225.  
  226.         dummy_hp->deftag = hp_deftag;
  227.         dummy_hp->defattr = hp_defattr;
  228.         dummy_hp->defent = hp_defent;
  229.  
  230.         /* assign new del_data-methodes */
  231.         dummy_hp->defattr->del_data = del_hscattr;
  232.         dummy_hp->defent->del_data = del_entity;
  233.         dummy_hp->deftag->del_data = del_hsctag;
  234.     }
  235.  
  236. #endif
  237.     return (dummy_hp);
  238. }
  239.  
  240. BOOL hsc_copy_base_info(HSCPRC * dest_hp, HSCPRC * dummy_hp)
  241. {
  242.     DLNODE *nd = dummy_hp->deftag->first;
  243.  
  244.     /* copy defined tags */
  245.     while (nd)
  246.     {
  247.         HSCTAG *newtag = cpy_hsctag((HSCTAG *) nd->data);
  248.         app_dlnode(dest_hp->deftag, (APTR) newtag);
  249.         nd = nd->next;
  250.     }
  251.  
  252.     return (TRUE);
  253. }
  254.  
  255. /*
  256.  * hsc_read_prefs
  257.  *
  258.  * try to open (any) config file and read preferences
  259.  * from it
  260.  */
  261. BOOL hsc_read_prefs(HSCPRC * hp, STRPTR prefs_fname)
  262. {
  263.     BOOL ok = FALSE;
  264.  
  265.     /* find prefs file */
  266.     if (!prefs_fname)
  267.         prefs_fname = find_prefs_fname(hp);
  268.  
  269.     /* status message */
  270.     if (prefs_fname)
  271.     {
  272.         dbg_disable(hp);
  273.  
  274.         hsc_status_file_begin(hp, prefs_fname);
  275.         ok = hsc_include_file(hp, prefs_fname,
  276.                               IH_PARSE_HSC | IH_NO_STATUS);
  277.         dbg_restore(hp);
  278.  
  279.         if (ok)
  280.         {
  281.             EXPSTR *msg = init_estr(32);
  282.             set_estr(msg, prefs_fname);
  283.             app_estr(msg, ": preferences read");
  284.             hsc_status_misc(hp, estr2str(msg));
  285.             del_estr(msg);
  286.         }
  287.     }
  288.     else
  289.     {
  290.         hsc_message(hp, MSG_NO_CONFIG,
  291.                     "can not open preferences file %q",
  292.                     CONFIG_FILE);
  293.     }
  294.  
  295.     return (ok);
  296. }
  297.  
  298. /*
  299.  * callback to display "project-file corrupt"-message
  300.  */
  301. static VOID msg_corrupt_pf(HSCPRJ * project, STRPTR reason)
  302. {
  303.     STRPTR prjtxt = "project-file corrupt";
  304.     HSCPRC *hp = (HSCPRC *) project->user_data;
  305.  
  306.     if (reason)
  307.         hsc_message(hp, MSG_CORRUPT_PRJFILE, "%s (%s)", prjtxt, reason);
  308.     else
  309.         hsc_message(hp, MSG_CORRUPT_PRJFILE, "%s", prjtxt);
  310. }
  311.  
  312. /*
  313.  * hsc_init_project
  314.  *
  315.  * read project-file
  316.  */
  317. BOOL hsc_init_project(HSCPRC * hp, STRPTR project_fname)
  318. {
  319.     BOOL ok = FALSE;
  320.  
  321.     /* init project */
  322.     hp->project = new_project();
  323.     hp->project->user_data = (APTR) hp;
  324.     hp->project->debug = hp->debug;
  325.     hp->project->CB_msg_corrupt_pf = msg_corrupt_pf;
  326.  
  327.     if (project_fname)
  328.     {
  329.         /*
  330.          * read project-data
  331.          */
  332.         D(fprintf(stderr, DHL "read project-file `%s'\n", project_fname));
  333.  
  334.         hsc_status_file_begin(hp, project_fname);
  335.  
  336.         /* read project-file */
  337.         hp->inpf = infopen(project_fname, 0);
  338.  
  339.         if (hp->inpf)
  340.         {
  341.             ok = hsc_project_read_file(hp->project, hp->inpf);
  342.             infclose(hp->inpf);
  343.             if (ok)
  344.             {
  345.                 /* message about success */
  346.                 EXPSTR *msg = init_estr(32);
  347.                 set_estr(msg, project_fname);
  348.                 app_estr(msg, ": project-file read");
  349.                 hsc_status_misc(hp, estr2str(msg));
  350.                 del_estr(msg);
  351.             }
  352.  
  353.             hp->inpf = NULL;
  354.         }
  355.         else
  356.         {
  357.             D(fprintf(stderr, DHL "  can't read project-file\n"));
  358.             ok = TRUE;
  359.             /* TODO: message "creating new one" */
  360.         }
  361.     }
  362.     else
  363.     {
  364.         D(fprintf(stderr, DHL "no project-file to load\n"));
  365.         ok = TRUE;
  366.     }
  367.  
  368.     if (ok)
  369.     {
  370.         /* dettach current document */
  371.         hsc_project_set_document(hp->project, hp->filename_document);
  372.     }
  373.  
  374.     return (ok);
  375. }
  376.  
  377. /*
  378.  * hsc_set_tagCB
  379.  */
  380. VOID hsc_set_tagCB(HSCPRC * hp, STRPTR name,
  381.                    BOOL(*op_hnd) (HSCPRC * inpf, HSCTAG * tag),
  382.                    BOOL(*cl_hnd) (HSCPRC * inpf, HSCTAG * tag))
  383. {
  384.     HSCTAG *tag = find_strtag(hp->deftag, name);
  385.  
  386.     if (tag && !(tag->option & HT_NOHANDLE))
  387.     {
  388.         /* set handles */
  389.         DC(fprintf(stderr, DHL "add handles for <%s> (%p,%p)\n",
  390.                    name, op_hnd, cl_hnd));
  391.         tag->o_handle = op_hnd;
  392.         tag->c_handle = cl_hnd;
  393.     }
  394. }
  395.  
  396. /*
  397.  * init_hsctags
  398.  *
  399.  * define hsc tags & attributes; assign tagCBs for them
  400.  *
  401.  * NOTE: this ones tricky, but a bit perverted somehow
  402.  */
  403. BOOL hsc_init_tagsNattr(HSCPRC * hp)
  404. {
  405. #define INCLUDE_ATTR " PRE:bool SOURCE:bool TEMPORARY:bool" \
  406.                      " INDENT:num TABSIZE:num=\"4\" "
  407.     BYTE i = 0;
  408.     BOOL ok = TRUE;
  409.     BOOL open_tag;
  410.     HSCTAG *tag;
  411.  
  412.     STRPTR hsc_prefs[] =
  413.     {
  414.     /*
  415.      * define hsc tags
  416.      */
  417.         HSC_COMMENT_STR " /SKIPLF /SPECIAL>",
  418.         HSC_ONLYCOPY_STR " /SPECIAL>",
  419.         HSC_INSEXPR_STR " /SPECIAL>",
  420.         HSC_DEFENT_STR " /SKIPLF NAME:string/r RPLC:string NUM:num>",
  421.         HSC_DEFICON_STR " /SKIPLF NAME:string/r>",
  422.         HSC_DEFINE_STR " /SKIPLF /SPECIAL>",
  423.         HSC_DEFTAG_STR " /SKIPLF /SPECIAL>",
  424.         HSC_ELSE_STR " /SKIPLF /MBI=\"" HSC_IF_STR "\">",
  425.         HSC_ELSEIF_STR " /SKIPLF /MBI=\"" HSC_IF_STR "\"" CONDITION_ATTR ":bool>",
  426.         HSC_MESSAGE_STR " /SKIPLF TEXT:string/r CLASS:enum(\"note|warning|error|fatal\")='note'>",
  427.         HSC_EXEC_STR " /SKIPLF COMMAND:string/r REMOVE:enum(\"on|off|auto\")=\"auto\" ATTRIBUTE:string INCLUDE:bool FILE:string " INCLUDE_ATTR ">",
  428.         HSC_EXPORT_STR " /SKIPLF FILE:string/r DATA:string/r APPEND:bool>",
  429.         HSC_IF_STR " /SKIPLF /CLOSE " CONDITION_ATTR ":bool>",
  430.         HSC_INSERT_STR " /OBSOLETE TEXT:string TIME:bool FORMAT:string>",
  431.         HSC_INCLUDE_STR " /SKIPLF FILE:string/r " INCLUDE_ATTR ">",
  432.         HSC_LET_STR " /SKIPLF /SPECIAL>",
  433.         HSC_MACRO_STR " /SKIPLF /SPECIAL>",
  434.         HSC_SOURCE_STR " /SKIPLF PRE:bool>",
  435.         NULL
  436.     };
  437.  
  438.     STRPTR hsc_attribs[] =
  439.     {
  440.     /*
  441.      * define hsc attributes
  442.      */
  443.         SYSTEM_ATTR ":string/c=\"" SYSTEM_ATTR_ID "\">",
  444.         ANCHOR_ATTR ":string=\"this is a feature, not a bug\">",
  445.         RESULT_ATTR ":num=\"0\">",
  446.         FILESIZEFORMAT_ATTR ":string=\"%a%u\">",
  447.         TIMEFORMAT_ATTR ":string=\"%d-%b-%Y, %H:%M\">",
  448.         LINEFEED_ATTR ":string>",
  449.         NULL};
  450.  
  451.     /* temporarily disable debugging output */
  452.     dbg_disable(hp);
  453.  
  454.     /* define hsc-tags */
  455.     i = 0;
  456.     while (!(hp->fatal) && hsc_prefs[i])
  457.     {
  458.         STRARR infname[20];
  459.  
  460.         sprintf(infname, SPECIAL_FILE_ID "init%3d", i);
  461.         hp->inpf = infopen_str(infname, hsc_prefs[i], 60);
  462.  
  463.         if (hp->inpf)
  464.         {
  465.             tag = def_tag_name(hp, &open_tag);
  466.             ok = (tag && def_tag_args(hp, tag));
  467.             infclose(hp->inpf);
  468.         }
  469.  
  470.         i++;
  471.  
  472.     }
  473.  
  474.     /* init hsc-attributes */
  475.     i = 0;
  476.     while (!(hp->fatal) && hsc_attribs[i])
  477.     {
  478.         hp->inpf =
  479.             infopen_str(SPECIAL_FILE_ID "init attr", hsc_attribs[i], 60);
  480.  
  481.         if (hp->inpf)
  482.         {
  483.             handle_hsc_define(hp, NULL);
  484.             infclose(hp->inpf);
  485.             hp->inpf = NULL;
  486.         }
  487.  
  488.         i++;
  489.     }
  490.  
  491.     /* assign "\n" to linefeed-attribute */
  492.     set_vartext(find_varname(hp->defattr, LINEFEED_ATTR), "\n");
  493.  
  494.     /* assign tag-callbacks to hsc-tags */
  495.     if (ok)
  496.     {
  497.         hsc_set_tagCB(hp, HSC_COMMENT_STR, handle_hsc_comment, NULL);
  498.         hsc_set_tagCB(hp, HSC_DEFENT_STR, handle_hsc_defent, NULL);
  499.         hsc_set_tagCB(hp, HSC_DEFICON_STR, handle_hsc_deficon, NULL);
  500.         hsc_set_tagCB(hp, HSC_DEFINE_STR, handle_hsc_define, NULL);
  501.         hsc_set_tagCB(hp, HSC_DEFTAG_STR, handle_hsc_deftag, NULL);
  502.         hsc_set_tagCB(hp, HSC_ELSE_STR, handle_hsc_else, NULL);
  503.         hsc_set_tagCB(hp, HSC_ELSEIF_STR, handle_hsc_elseif, NULL);
  504.         hsc_set_tagCB(hp, HSC_EXEC_STR, handle_hsc_exec, NULL);
  505.         hsc_set_tagCB(hp, HSC_EXPORT_STR, handle_hsc_export, NULL);
  506.         hsc_set_tagCB(hp, HSC_IF_STR, handle_hsc_if, handle_hsc_cif);
  507.         hsc_set_tagCB(hp, HSC_INCLUDE_STR, handle_hsc_include, NULL);
  508.         hsc_set_tagCB(hp, HSC_INSERT_STR, handle_hsc_insert, NULL);
  509.         hsc_set_tagCB(hp, HSC_INSEXPR_STR, handle_hsc_insert_expression, NULL);
  510.         hsc_set_tagCB(hp, HSC_COMMENT_STR, handle_hsc_comment, NULL);
  511.         hsc_set_tagCB(hp, HSC_LET_STR, handle_hsc_let, NULL);
  512.         hsc_set_tagCB(hp, HSC_MACRO_STR, handle_hsc_macro, NULL);
  513.         hsc_set_tagCB(hp, HSC_MESSAGE_STR, handle_hsc_message, NULL);
  514.         hsc_set_tagCB(hp, HSC_ONLYCOPY_STR, handle_hsc_onlycopy, NULL);
  515.         hsc_set_tagCB(hp, HSC_SOURCE_STR, handle_hsc_source, NULL);
  516.     }
  517.  
  518.     /* restore debugging output */
  519.     dbg_restore(hp);
  520.  
  521.     return (ok);
  522. }
  523.  
  524. /*
  525.  * hsc_init_basicEntities
  526.  *
  527.  * create basic entities (&, >, <, ")
  528.  * (should be called BEFORE hsc_read_prefs())
  529.  */
  530. BOOL hsc_init_basicEntities(HSCPRC * hp)
  531. {
  532.     BOOL ok = TRUE;
  533.  
  534.     /* entities */
  535.     ok &= add_ent(hp->defent, "amp", NULL, 0);  /* & */
  536.     ok &= add_ent(hp->defent, "lt", NULL, 0);   /* < */
  537.     ok &= add_ent(hp->defent, "gt", NULL, 0);   /* > */
  538.     ok &= add_ent(hp->defent, "quot", NULL, 0);         /* q */
  539.  
  540.     return (ok);
  541. }
  542.  
  543. /*
  544.  * hsc_assign_tagCBs
  545.  *
  546.  * assign tag-callbacks to standard html-tags
  547.  * (MUST ONLY be called AFTER hsc_read_prefs())
  548.  */
  549. BOOL hsc_assign_tagCBs(HSCPRC * hp)
  550. {
  551.     hsc_set_tagCB(hp, "!", handle_sgml_comment, NULL);
  552.     hsc_set_tagCB(hp, "A", handle_anchor, handle_canchor);
  553.     hsc_set_tagCB(hp, "BASE", handle_base, NULL);
  554.     hsc_set_tagCB(hp, "BLINK", handle_blink, NULL);
  555.     hsc_set_tagCB(hp, "H1", handle_heading, NULL);
  556.     hsc_set_tagCB(hp, "H2", handle_heading, NULL);
  557.     hsc_set_tagCB(hp, "H3", handle_heading, NULL);
  558.     hsc_set_tagCB(hp, "H4", handle_heading, NULL);
  559.     hsc_set_tagCB(hp, "H5", handle_heading, NULL);
  560.     hsc_set_tagCB(hp, "H6", handle_heading, NULL);
  561.     hsc_set_tagCB(hp, "IMG", handle_img, NULL);
  562.     hsc_set_tagCB(hp, "PRE", handle_pre, handle_end_pre);
  563.  
  564.     return (TRUE);
  565. }
  566.  
  567. /*
  568.  * hsc_init_hscprc
  569.  *
  570.  * - init all items of hsc-process
  571.  * - create hsc-tags & special atttributes
  572.  * - read preferences file
  573.  * - assign tag-callbacks
  574.  */
  575. BOOL hsc_init_hscprc(HSCPRC * hp, STRPTR prefs_fname)
  576. {
  577.     BOOL ok = FALSE;            /* return value */
  578.  
  579.     if (hsc_init_tagsNattr(hp)
  580.         && hsc_init_basicEntities(hp)
  581.         && hsc_read_prefs(hp, prefs_fname)
  582.         && hsc_assign_tagCBs(hp)
  583.         )
  584.     {
  585.         /* return sucess */
  586.         ok = TRUE;
  587.  
  588.         /* printf list of defined tags & entities */
  589.         DC(
  590.               {
  591.               DLNODE * nd;
  592.               HSCENT * ent;
  593.  
  594.               nd = hp->defent->first;
  595.               if (nd)
  596.               {
  597.               fprintf(stderr, DHL "Known entities:");
  598.  
  599.               while (nd)
  600.               {
  601.               ent = (HSCENT *) nd->data;
  602.               fprintf(stderr, " &%s;", ent->name);
  603.               nd = nd->next;
  604.               }
  605.               fprintf(stderr, "\n");
  606.               }
  607.  
  608.               nd = hp->deftag->first;
  609.               if (nd)
  610.               {
  611.               fprintf(stderr, DHL "Known tags:");
  612.               while (nd)
  613.               {
  614.               prt_tag(stderr, nd->data);
  615.               nd = nd->next;
  616.               }
  617.               fprintf(stderr, "\n");
  618.               }
  619.  
  620.               }
  621.         );                      /* DC */
  622.     }
  623.  
  624.     hp->click_here_str =
  625.         get_vartext_byname(hp->defattr, CLICK_HERE_ATTR);
  626.     hp->color_names =
  627.         get_vartext_byname(hp->defattr, COLOR_NAMES_ATTR);
  628.  
  629.     return (ok);
  630. }
  631.  
  632.